/*******************************************************************************
 * eWisdom : a Distributed File Sharing Room on top of a p2p Overlay Network
 * Copyright (C) 2009-2010 Jesus Mari Aguirre
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************/

package org.jma.app.ewisdom.services;

import easypastry.dht.DHTHandler;
import easypastry.dht.DHTException;
import easypastry.core.PastryKernel;
import easypastry.util.Utilities;

import org.jma.app.ewisdom.entities.EntityWithACL;
import org.jma.app.ewisdom.entities.User;
import org.jma.app.ewisdom.entities.UserVector;
import org.jma.app.ewisdom.exceptions.FileException;
import org.jma.app.ewisdom.exceptions.GroupException;
import org.jma.app.ewisdom.exceptions.UserException;
import org.jma.lib.soap.SOAPProxy;
import org.jma.lib.soap.sessions.SOAPSession;


import java.util.HashMap;
import java.util.Vector;

/**
 * SrvUserManager class allows the management of Users. It publishes
 * methods as services described below.<br>
 * @author Jesus Mari, jesmari@ono.com
 * @version 1.0
 * @since 1.0
 */
public class SrvUserManager {

	/**
	 * Checks if a user is a wheel group member
	 * @param currentUser
	 * @return true or false
	 * @throws GroupException
	 */
	private boolean checkGroup(String currentUser) throws  UserException{
		//if (currentUser.equals(userName)) return false;		
		HashMap soapParams=new HashMap();
		soapParams.put("userName", currentUser);
		User u=this.getUserByUserName(soapParams);
		Vector g=u.getGroups();
		if (g.contains("wheel")) return false;
		return true;
	}
	
	/**
	 * gets a User
	 * @param soapParams <code>userName</code> the user name.
	 * @return a User
	 * @throws UserException
	 */
	public User getUserByUserName (HashMap soapParams) throws UserException {
		SOAPSession session = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession));
		if (session!=null) {
			String currentUser = session.getUserName();
			if (checkGroup(currentUser)) throw new UserException("Insufficient privileges");
		}
		String username=(String)soapParams.get("userName");

		User user;
		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			user = (User) dhtUser.get(username);
			
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}      

		return user;
	}
	

	/**
	 * Modifies the user Data
	 * @param soapParams <code>userName</code> the user name, <code>name</code> the long name,
	 * <code>password</code> the user password, <code>email</code> the user email
	 * @return a User Modified
	 * @throws UserException
	 */
	public User modifyUser(HashMap soapParams) throws UserException {
		String username=(String)soapParams.get("userName");
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new UserException("Insufficient privileges");
		User user;
		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			user = (User) dhtUser.get(username);
			user.setName((String)soapParams.get("name"));
			user.setPassword((String)soapParams.get("password"));
			user.setEmailAddress((String)soapParams.get("email"));
			
			dhtUser.put(user.getUserName(),user);
			removeUserFromCollection(user);
			addUserToCollection(user);
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}      

		return user;
	}

	/**
	 * Joins a user to a group
	 * @param soapParams <code>userName</code> the user name, <code>groupName</code> the Group name
	 * @return
	 * @throws UserException
	 */
	protected User joinUserToGroup(HashMap soapParams) throws UserException {
		String username=(String)soapParams.get("userName");
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new UserException("Insufficient privileges");
		User user;
		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			user = (User) dhtUser.get(username);
			user.joinToGroup((String)soapParams.get("groupName"));
			dhtUser.put(user.getUserName(),user);
			removeUserFromCollection(user);
			addUserToCollection(user);
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}      

		return user;
	}
	
	/**
	 * Adds a new User
	 * @param soapParams <code>userName</code> the user name, <code>name</code> the long name,
	 * <code>password</code> the user password, <code>email</code> the user email
	 * @return a new User
	 * @throws UserException
	 */
	public User addUser (HashMap soapParams) throws UserException {
		SOAPSession session = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession));
		if (session!=null) {
			String currentUser= session.getUserName();
			if (checkGroup(currentUser)) throw new UserException("Insufficient privileges");
		}
		
		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			User user= new User();
			user.setName((String)soapParams.get("name"));
			user.setPassword((String)soapParams.get("password"));
			user.setEmailAddress((String)soapParams.get("email"));
			user.setUserName((String)soapParams.get("userName"));
			dhtUser.put(user.getUserName(),user);
			addUserToCollection(user);


			return user;
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}
	}

	/**
	 * adds a User to the UserVector
	 * @param user a User object
	 * @throws UserException
	 */
	private void addUserToCollection  (User user) throws UserException {

		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			UserVector set = (UserVector) dhtUser.get("users.Vector");
		
			if (set == null) {
				set = new UserVector();
			}
			set.add(user.clone());
			dhtUser.put("users.Vector", set);
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}
	}

	/**
	 * removes a User from the UserVector
	 * @param user a User object
	 * @throws UserException
	 */
	private void removeUserFromCollection  (User user) throws UserException {

		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			UserVector set = (UserVector) dhtUser.get("users.Vector");
			if (set == null) {
				set = new UserVector();
			}
			set.remove(user);
			dhtUser.put("users.Vector", set);
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}
	}    

	/**
	 * gets all users
	 * @param soapParams No parameters defined
	 * @return
	 * @throws UserException
	 */
	public UserVector getUsers (HashMap soapParams) throws UserException{
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new UserException("Insufficient privileges");

		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			UserVector set = (UserVector) dhtUser.get("users.Vector");
			return set;
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}
	}

	/**
	 * Removes a User.
	 * @param soapParams <code>userName</code> the user name.
	 * @return
	 * @throws UserException
	 */
	public User removeUser(HashMap soapParams) throws UserException{
		String currentUser = ((SOAPSession)soapParams.get(SOAPProxy.SOAPSession)).getUserName();
		if (checkGroup(currentUser)) throw new UserException("Insufficient privileges");

		String username=(String)soapParams.get("userName");   	  
		User user;
		try {
			DHTHandler dhtUser = PastryKernel.getDHTHandler(Utilities.generateStringHash("p2p://org.jma.app.ewisdom.users"));

			user = (User) dhtUser.get(username);
			dhtUser.remove(username);
			removeUserFromCollection(user);
		} catch (DHTException e) {
			throw new UserException(e.getMessage());
		}      

		return user;

	}
}
